/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ac.pbp.dao.impl;

import ac.pbp.core.db.DaoHelper;
import ac.pbp.core.exception.DataAdditionException;
import ac.pbp.core.exception.DataDeletionException;
import ac.pbp.core.exception.DataModificationException;
import ac.pbp.core.filter.FilterCriteria;
import ac.pbp.dao.BukuUserDao;
import ac.pbp.dto.filter.BukuUserFilterCriteria;
import ac.pbp.model.BukuUser;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Order;
import org.springframework.stereotype.Component;

/**
 *
 * @author Kim
 */
@Component
public class BukuUserDaoImpl extends DaoHelper implements BukuUserDao {

    @Override
    public List<BukuUser> loadAll(Long start, Long max) {
        return getSession().createQuery("FROM BukuUser ORDER BY kodeUser ASC").setCacheable(true).list();
    }

    @Override
    public List<BukuUser> filter(FilterCriteria filterCriteria) {
        BukuUserFilterCriteria filter = (BukuUserFilterCriteria) filterCriteria;
        Criteria criteria = filterRoot(filter, getSession().createCriteria(BukuUser.class));
        long start = (filter.getPage() - 1) * filter.getMax();
        criteria.setFirstResult(Long.valueOf(start).intValue());
        criteria.setMaxResults(Long.valueOf(filter.getMax()).intValue());
        return criteria.setCacheable(true).list();
    }

    @Override
    public Long getMax(FilterCriteria filterCriteria) {
        BukuUserFilterCriteria filter = (BukuUserFilterCriteria) filterCriteria;
        Criteria criteria = filterRoot(filter, getSession().createCriteria(BukuUser.class));
        return new Integer(criteria.setCacheable(true).list().size()).longValue();
    }

    @Override
    public Long getMax() {
        return (Long) getSession().createQuery("SELECT COUNT(*) FROM BukuUser").setCacheable(true).uniqueResult();
    }

    @Override
    public void add(BukuUser bean) throws DataAdditionException {
        try {
            getHibernateTemplate().save(bean);
        } catch (Exception e) {
            throw new DataAdditionException("Add New BukuUser Failed!", e);
        }
    }

    @Override
    public BukuUser load(String kodeBukuUser) {
        return (BukuUser) getSession().load(BukuUser.class, kodeBukuUser);
    }

    @Override
    public List<BukuUser> loadAll() {
        return getSession().createQuery("FROM BukuUser ORDER BY kodeUser ASC").setCacheable(true).list();
    }

    @Override
    public void update(BukuUser bean) throws DataModificationException {
        try {
            getHibernateTemplate().update(bean);
        } catch (Exception e) {
            throw new DataModificationException("Update BukuUser Failed!", e);
        }
    }

    @Override
    public void delete(BukuUser bean) throws DataDeletionException {
        try {
            getHibernateTemplate().delete(bean);
        } catch (Exception e) {
            throw new DataDeletionException("Delete BukuUser Failed!", e);
        }
    }

    public Criteria filterRoot(BukuUserFilterCriteria filter, Criteria criteria) {
        criteria.addOrder(Order.asc("kodeUser"));
        System.out.println("masuk filterRoot?");

        return criteria;
    }

    @Override
    public void deleteMyBooks(String kodeUser, String kodeBuku) {
        getSession().createSQLQuery("DELETE FROM buku_user WHERE kode_user = \"" + kodeUser + "\" and kode_buku =  \"" + kodeBuku + "\" ")
                .executeUpdate();
    }

    @Override
    public BukuUser loadBukuUser(String kodeUser, String kodeBuku) {
        
        return (BukuUser)getSession().createSQLQuery("SELECT * FROM buku_user WHERE kode_user = \"" + kodeUser + "\" and kode_buku =  \"" + kodeBuku + "\" ")
                .addEntity(BukuUser.class)
                .setCacheable(true)
                .uniqueResult();
    }

    @Override
    public List<BukuUser> loadReview(String kodeBuku, String kodeUser) {
        
        Query q = getSession().createSQLQuery("SELECT * FROM buku_user WHERE kode_buku = :kodeBuku AND kode_user NOT IN (:kodeUser) ")
                .addEntity(BukuUser.class)
                .setCacheable(true);
        q.setParameter("kodeBuku", kodeBuku);
        q.setParameter("kodeUser", kodeUser);
        
        return q.list();
    }

}
